package com.pn.controller;

import com.google.code.kaptcha.Producer;
import com.pn.entity.CurrentUser;
import com.pn.entity.LoginUser;
import com.pn.entity.Result;
import com.pn.entity.User;
import com.pn.service.UserService;
import com.pn.utils.DigestUtil;
import com.pn.utils.TokenUtils;
import com.pn.utils.WarehouseConstants;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.concurrent.TimeUnit;

/**
 * @Author : LH
 * @create 2023/12/10 19:21
 */
@RestController
public class LoginController {
	// Resource 按照名字自动注入DefaultKaptcha的bean对象，Autowired按照类型自动注入
	@Resource(name = "captchaProducer")  // 生成验证码图片的
	private Producer producer;
	
	// 注入redis模板
	@Autowired
	private StringRedisTemplate redisTemplate;
	
	@RequestMapping("/captcha/captchaImage")
	public void captchaImage(HttpServletResponse response)  {
		// 先定义响应对象的字节输出流
		ServletOutputStream out = null;
		try {
			// 生成验证码图片的文件
			String text = producer.createText();
			// 使用验证码问本生成验证码图片,BufferedImage对象就代表生成的验证码图片，在内存中
			BufferedImage image = producer.createImage(text);
			// 把验证码文本作为键保存到redis中
			// text是键，值为""空就行，60*30是半小时，单位为秒
			redisTemplate.opsForValue().set(text,"",60*30, TimeUnit.SECONDS);
			
			// 将验证码图片响应给前端：
			// 设置响应正文image/jpeg
			response.setContentType("image/jpeg");
			// 拿到响应对象的字节输出流
			out = response.getOutputStream();
			// 将响应对象的字节输出流写入验证码图片，给前端写入
			ImageIO.write(image,"jpg",out);
			// 刷新
			out.flush();
		}catch (IOException e){
			e.printStackTrace();
		} finally {
			// 关闭字节输出流
			if (out != null){
				try {
					out.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
	
	/**
	 * 登录的url接口/login
	 * @param loginUser 表示接收并封装前端传递的登录的用户信息的json数据。
	 * @return 返回值施Result对象，表示向前端响应响应结果Result对象转的json串，包含响应状态码 成功失败响应，响应信息，响应数据
	 */
	
	// 注入UserService的bean对象
	@Autowired
	private UserService userService;
	
	// 注入TokenUtils的bean对象
	@Autowired
	private TokenUtils tokenUtils;
	
	@RequestMapping("/login")
	public Result login(@RequestBody LoginUser loginUser){
		
		// 拿到客户录入的验证码
		String code = loginUser.getVerificationCode();
		if(!redisTemplate.hasKey(code)){ // 验证码不存在
			return Result.err(Result.CODE_ERR_BUSINESS,"验证码错误！");
		}
		
		// 根据账号查询用户
		User user = userService.findUserByCode(loginUser.getUserCode());
		if(user!=null){ // 账号存在
			// 密码匹配
			if(user.getUserState().equals(WarehouseConstants.USER_STATE_PASS)){ // 用户已审核return Result.success("登录成功");
				// 拿到用户录入的密码
				String userPwd = loginUser.getUserPwd();
				// 进行md5加密
				userPwd = DigestUtil.hmacSign(userPwd);
				if (userPwd.equals(user.getUserPwd())) { // 密码合法
					// 生成jwt token并存储到redis
					CurrentUser currentUser = new CurrentUser();
					String token = tokenUtils.loginSign(currentUser, userPwd);
					// 向客户端响应jwt token
					return Result.ok("登录成功！",token);
				} else { // 密码非法
					return Result.err(Result.CODE_ERR_BUSINESS,"密码错误！");
				}
			}else{ // 用户未审核
				return Result.err(Result.CODE_ERR_BUSINESS,"用户未审核!");
			}
		}else { // 账号不存在
			return Result.err(Result.CODE_ERR_BUSINESS,"账号不存在！");
		}
	}
	
	// 获取当前登录的用户信息的url接口/curr-user
	// WarehouseConstants.HEADER_TOKEN_NAME表示将请求头token的值(前端归还的token赋值给请求处理方法入参变量token)
	@RequestMapping("/curr-user")
	public Result currentUser(@RequestHeader(WarehouseConstants.HEADER_TOKEN_NAME) String token){
		// 解析token拿到封装了当前登录用户信息的CurrentUser对象
		CurrentUser currentUser = tokenUtils.getCurrentUser(token);
		// 响应
		return Result.ok(currentUser);
	}
}
